From b2e339351a59eaa68337fe72f90beeba376ea8b4 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 2 Sep 2005 17:53:04 +0000 Subject: [PATCH] Handle page overlapping copies. Signed-Off-By: Leendert van Doorn --- xen/arch/x86/vmx.c | 51 +++++++++++++++++++++------------------ xen/include/asm-x86/vmx.h | 3 +++ 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index 6621b0bafe..b192bb05e6 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -699,29 +699,34 @@ static void vmx_io_instruction(struct cpu_user_regs *regs, vmx_wait_io(); } -enum { COPY_IN = 0, COPY_OUT }; - -static inline int +int vmx_copy(void *buf, unsigned long laddr, int size, int dir) { - char *addr; unsigned long mfn; + char *addr; + int count; - if ( (size + (laddr & (PAGE_SIZE - 1))) >= PAGE_SIZE ) - { - printf("vmx_copy exceeds page boundary\n"); - return 0; - } + while (size > 0) { + count = PAGE_SIZE - (laddr & ~PAGE_MASK); + if (count > size) + count = size; - mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT); - addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK); + mfn = get_mfn_from_pfn(laddr >> PAGE_SHIFT); + /* XXX check whether laddr is valid */ + addr = (char *)map_domain_page(mfn) + (laddr & ~PAGE_MASK); - if (dir == COPY_IN) - memcpy(buf, addr, size); - else - memcpy(addr, buf, size); + if (dir == VMX_COPY_IN) + memcpy(buf, addr, count); + else + memcpy(addr, buf, count); + + unmap_domain_page(addr); + + laddr += count; + buf += count; + size -= count; + } - unmap_domain_page(addr); return 1; } @@ -908,7 +913,7 @@ vmx_assist(struct vcpu *d, int mode) u32 cp; /* make sure vmxassist exists (this is not an error) */ - if (!vmx_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), COPY_IN)) + if (!vmx_copy(&magic, VMXASSIST_MAGIC_OFFSET, sizeof(magic), VMX_COPY_IN)) return 0; if (magic != VMXASSIST_MAGIC) return 0; @@ -922,20 +927,20 @@ vmx_assist(struct vcpu *d, int mode) */ case VMX_ASSIST_INVOKE: /* save the old context */ - if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), COPY_IN)) + if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN)) goto error; if (cp != 0) { if (!vmx_world_save(d, &c)) goto error; - if (!vmx_copy(&c, cp, sizeof(c), COPY_OUT)) + if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_OUT)) goto error; } /* restore the new context, this should activate vmxassist */ - if (!vmx_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), COPY_IN)) + if (!vmx_copy(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp), VMX_COPY_IN)) goto error; if (cp != 0) { - if (!vmx_copy(&c, cp, sizeof(c), COPY_IN)) + if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN)) goto error; if (!vmx_world_restore(d, &c)) goto error; @@ -949,10 +954,10 @@ vmx_assist(struct vcpu *d, int mode) */ case VMX_ASSIST_RESTORE: /* save the old context */ - if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), COPY_IN)) + if (!vmx_copy(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp), VMX_COPY_IN)) goto error; if (cp != 0) { - if (!vmx_copy(&c, cp, sizeof(c), COPY_IN)) + if (!vmx_copy(&c, cp, sizeof(c), VMX_COPY_IN)) goto error; if (!vmx_world_restore(d, &c)) goto error; diff --git a/xen/include/asm-x86/vmx.h b/xen/include/asm-x86/vmx.h index 1d9b74dfb5..c03559849f 100644 --- a/xen/include/asm-x86/vmx.h +++ b/xen/include/asm-x86/vmx.h @@ -471,4 +471,7 @@ static inline int iopacket_port(struct domain *d) void load_cpu_user_regs(struct cpu_user_regs *regs); void store_cpu_user_regs(struct cpu_user_regs *regs); +enum { VMX_COPY_IN = 0, VMX_COPY_OUT }; +int vmx_copy(void *buf, unsigned long laddr, int size, int dir); + #endif /* __ASM_X86_VMX_H__ */ -- 2.30.2